using System.Collections.Generic;
using System.Xml;
using mock_ehr_lib.Data.LookupServices;

namespace mock_ehr_lib.Model.Summary
{
    public class AlertItem
    {
        public string Substance { get; set; }
        public string Reaction { get; set; }
        public string Status { get; set; }
        public static IEnumerable<AlertItem> FromCCD(XmlDocument ccdXml, XmlNamespaceManager namespaceManager)
        {
            const string alertsXPath = "//ns:observation[ns:templateId[@root='2.16.840.1.113883.10.20.1.18']]";
            var alertNodes = ccdXml.SelectNodes(alertsXPath, namespaceManager);
            var alertItems = new List<AlertItem>();
            if (alertNodes != null)
            {
                var alertNodeEnumerator = alertNodes.GetEnumerator();
                if (alertNodeEnumerator != null)
                {
                    while (alertNodeEnumerator.MoveNext())
                    {
                        var alertItem = new AlertItem();
                        var current = alertNodeEnumerator.Current as XmlNode;
                        var substanceNode =
                            current.SelectSingleNode("./ns:participant/ns:participantRole/ns:playingEntity/ns:code", namespaceManager);
                        if (substanceNode != null)
                        {
                            var codeSystem = substanceNode.Attributes["codeSystem"] == null ? null : substanceNode.Attributes["codeSystem"].Value;
                            var code = substanceNode.Attributes["code"] == null ? null : substanceNode.Attributes["code"].Value;
                            if (string.IsNullOrWhiteSpace(codeSystem) || string.IsNullOrWhiteSpace(code))
                            {
                                alertItem.Substance =
                                substanceNode.Attributes["displayName"] == null
                                    ? null
                                    : substanceNode.Attributes["displayName"].InnerText;
                            }
                            else
                            {
                                var lookupService = LookupServiceFactory.GetLookupServiceByCodeSystem(codeSystem);
                                alertItem.Substance = lookupService.GetDescriptionByCode(code);
                            }
                        }
                        var reactionNode =
                            current.SelectSingleNode(
                                ".//ns:observation[ns:templateId[@root='2.16.840.1.113883.10.20.1.54']]/ns:value", namespaceManager);
                        if (reactionNode != null)
                        {
                            var codeSystem = reactionNode.Attributes["codeSystem"] == null ? null : reactionNode.Attributes["codeSystem"].Value;
                            var code = reactionNode.Attributes["code"] == null ? null : reactionNode.Attributes["code"].Value;
                            if (string.IsNullOrWhiteSpace(codeSystem) || string.IsNullOrWhiteSpace(code))
                            {
                                alertItem.Reaction =
                                reactionNode.Attributes["displayName"] == null
                                    ? null
                                    : reactionNode.Attributes["displayName"].InnerText;
                            }
                            else
                            {
                                var lookupService = LookupServiceFactory.GetLookupServiceByCodeSystem(codeSystem);
                                alertItem.Reaction = lookupService.GetDescriptionByCode(code);
                            }
                        }
                        alertItems.Add(alertItem);

                        var statusNode =
                            current.SelectSingleNode(".//ns:observation[ns:templateId[@root='2.16.840.1.113883.10.20.1.39']]/ns:value", namespaceManager);
                        if (statusNode != null)
                        {
                            var codeSystem = statusNode.Attributes["codeSystem"] == null ? null : statusNode.Attributes["codeSystem"].Value;
                            var code = statusNode.Attributes["code"] == null ? null : statusNode.Attributes["code"].Value;
                            if (string.IsNullOrWhiteSpace(codeSystem) || string.IsNullOrWhiteSpace(code))
                            {
                                alertItem.Status =
                                statusNode.Attributes["displayName"] == null
                                    ? null
                                    : statusNode.Attributes["displayName"].InnerText;
                            }
                            else
                            {
                                var lookupService = LookupServiceFactory.GetLookupServiceByCodeSystem(codeSystem);
                                alertItem.Status = lookupService.GetDescriptionByCode(code);
                            }
                        }
                    }
                }
            }
            return alertItems;
        }
    }
}